const express = require('express')
const app = express()

const server = require('http').Server(app)
const io = require('socket.io')(server)

const {server_port} = require('./config')

const { parseToken } = require('./util')

const { query } = require('./db')

// 跨域
const cors = require("cors");
app.use(cors());

const bodyParser = require('body-parser')
require('body-parser-xml')(bodyParser)   // 解析 xml

app.use(bodyParser.json())   // 允许接收 JSON 格式的数据，前端使用 axios 包调用接口时使用 JSON
app.use(bodyParser.urlencoded({ extended: true })) // 接收 x-www 格式的数据，给 postman 测试 用的
app.use(bodyParser.xml())

// 把图片目录暴露出来
app.use('/uploads', express.static('uploads'))

const fs = require('fs')
// 1. 直接读取 routers 目录下所有的文件
const routerFiles = fs.readdirSync('./routers')
// 2. 循环所有的文件实现加载
routerFiles.forEach(v => {

    // 如果是目录就再读取
    if (v.indexOf('.js') === -1) {   // v  中是否有 .js
        // 读取子目录
        const routerFiles1 = fs.readdirSync('./routers/' + v)
        routerFiles1.forEach(v1 => {
            let name = v1.replace('.js', '')
            app.use('/' + v + '/' + name, require('./routers/' + v + '/' + name))
        })
    } else {
        // 如果是文件就直接加载
        // 提取文件（去掉.js)
        let name = v.replace('.js', '')
        app.use('/' + name, require('./routers/' + name))
    }
})

// 统一处理网站中所有的错误（网站中一有错误就会跳到这里来执行）
app.use((err, req, res, next) => {
    res.json({
        'ok': 0,
        'error': err
    })
})

server.listen(server_port, () => {
    console.log('成功！'+server_port)
})

io.on('connect', async client => {

    // 1. 接收参数
    let room = client.handshake.query.room     // 房间ID
    let token = client.handshake.query.token   // 令牌

    // 2. 进入房间
    client.join(room)

    // 3. 解析令牌
    let userId = null
    let username = '游客'
    let avatar
    if(token) {
        // 解析令牌
        userId = parseToken(token)
        // 根据ID到数据库中取出头像和用户名
        if(userId) {
            let ret = await query('SELECT name,avatar FROM users WHERE id=?', userId)
            username = ret[0].name 
            avatar = ret[0].avatar 
        }
    }

    // m 频道：文本消息
    client.on('m', data => {
        // 转发消息到 m 频道
        io.in(room).emit('m', {
            u: username,
            a: avatar,
            m: data
        })
    })

    // g 频道：打赏礼物
    // giftId：礼物ID
    client.on('g', giftId => {
        // 转发消息到 g 频道
        io.in(room).emit('g', {
            u: username,   // 用户名
            a: avatar,     // 头像
            g: giftId
        })
    })

    // （系统使用的频道）
    io.in(room).emit('n', username + ' 进入了房间~')

    client.on('disconnect', () => {
        client.to(room).emit('n', username + ' 离开了房间~')
    })
})
